package com.adee.juc;

import com.adee.util.Utils;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程各种状态及显示值
 *
 */
public class Test005_ThreadState {
    public static void main(String[] args) {
        // park();
        // lock();
        // lockCondition();
        // synchronizedMonitor();
        synchronizedWait();
    }

    // 调用LockSupport.park()方法，线程状态
    public static void park() {
        Thread t = new Thread(() -> {
            LockSupport.park();
        });
        t.start();
        Utils.sleep(1);
        System.out.println("state:" + t.getState());
    }
    // ReentrantLock.lock()方法
    public static void lock() {
        final ReentrantLock lock = new ReentrantLock();
        Runnable r = () -> {
            lock.lock();
            try {
                Utils.sleep(500);
            } finally {
                lock.unlock();
            }
        };
        Thread t1 = new Thread(r, "Thread-1");
        Thread t2 = new Thread(r, "Thread-2");
        t1.start();
        t2.start();
        Utils.sleep(3);
        System.out.println("Thread-1 state: " + t1.getState());
        System.out.println("Thread-2 state: " + t2.getState());
    }
    // ReentrantLock.lock()中调用Condition条件等待
    // 一个lock下可以创建多个Condition，注意，调用Condition.wait()一定要在lock()之后，否则抛IllegalMonitorStateException异常
    public static void lockCondition() {
        ReentrantLock lock = new ReentrantLock();
        Condition conNotEmpty = lock.newCondition();
        Condition conNotFull = lock.newCondition();
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                conNotEmpty.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "Thread-1");
        Thread t2 = new Thread(() -> {
            lock.lock();
            try {
                conNotFull.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "Thread-2");
        t1.start();
        t2.start();
        Utils.sleep(3);
        System.out.println("Thread-1 state: " + t1.getState());
        System.out.println("Thread-2 state: " + t2.getState());
    }
    // synchronized上未竞争到锁而阻塞
    public static void synchronizedMonitor() {
        Object monitor = new Object(); // 管程对象，英文名叫Monitor
        Runnable r = ()->{
            synchronized (monitor) {
                Utils.sleep(500);
            }
        };
        Thread t1 = new Thread(r, "Thread-1");
        Thread t2 = new Thread(r, "Thread-2");
        t1.start();
        t2.start();
        Utils.sleep(3);
        System.out.println("Thread-1 state: " + t1.getState());
        System.out.println("Thread-2 state: " + t2.getState());
    }
    // synchronized中调用Object.wait()
    public static void synchronizedWait() {
        Object monitor = new Object();
        Runnable r = ()->{
            synchronized (monitor) {
                try {
                    monitor.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread t1 = new Thread(r, "Thread-1");
        Thread t2 = new Thread(r, "Thread-2");
        t1.start();
        t2.start();
        Utils.sleep(3);
        System.out.println("Thread-1 state: " + t1.getState());
        System.out.println("Thread-2 state: " + t2.getState());
    }
}
